package com.book.service;

import com.alipay.api.internal.util.AlipaySignature;
import com.book.ordermanagement.state.OrderState;
import com.book.ordermanagement.state.OrderStateChangeAction;
import com.book.pay.facade.PayFacade;
import com.book.pay.strategy.AlipayStrategy;
import com.book.pojo.Order;
import com.book.service.inter.OrderServiceInterface;
import com.book.utils.Constants;
import com.book.utils.RedisUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.statemachine.StateMachine;
import org.springframework.statemachine.persist.StateMachinePersister;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.UUID;

/**
 * @param
 * @author
 * @version 1.0.4
 * @description: TODO
 * @date 2023/12/20 21:23
 */
@Service
public class OrderService implements OrderServiceInterface {

    @Autowired
    private StateMachine<OrderState, OrderStateChangeAction> stateMachine;

    @Autowired
    private StateMachinePersister<OrderState, OrderStateChangeAction, String> stateMachinePersister;



    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private AlipayStrategy alipayStrategy;

    @Autowired
    private PayFacade payFacade;

    public Order createOrder(String productId) {
        String orderId = UUID.randomUUID() + productId;
        // 创建订单并存储到redis中
        Order order = Order.builder()
                .orderId(orderId)
                .productId(productId)
                .orderState(String.valueOf(OrderState.ORDER_WAIT_PAY)).build();
        redisUtils.set(orderId, order, 900);
        return order;
    }

    public Order payOrder(String orderId) {
        Order order = (Order) redisUtils.get(orderId);
        // 调整订单状态放入到message中
        Message<OrderStateChangeAction> message = MessageBuilder.withPayload(OrderStateChangeAction.PAY_ORDER)
                .setHeader("order", order).build();
        // 将message信息传递给spring状态机
        if (changeStateAction(message, order)) {
            return order;
        }
        return null;
    }

    private boolean changeStateAction(Message<OrderStateChangeAction> message, Order order) {
        try {
            // 状态机启动
            stateMachine.start();
            // 把状态机信息和订单号存储到redis中
            stateMachinePersister.restore(stateMachine,order.getOrderId()+"OYZ");
            // 将message信息发送给监听者
            return stateMachine.sendEvent(message);
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            stateMachine.stop();
        }
    }

    /**
     * 支付宝回调逻辑
     * @param request
     * @return
     */
    public String alipayCallback(HttpServletRequest request) {
        Map<String, String[]> parameterMap = request.getParameterMap();
        Map<String, String> params = new HashMap<>();
        try {
            for (Iterator<String> iterator = parameterMap.keySet().iterator(); iterator.hasNext(); ) {
                String key = iterator.next();
                String[] strings = parameterMap.get(key);
                String value = null;
                for (int i = 0; i < strings.length; i++) {
                    value = (i == strings.length - 1) ? value + strings[i] : value + strings[i] + ",";
                }
                value = new String(value.getBytes("ISO-8859-1"));
                params.put(key, value);
            }
            // 验证签名，确保回调接口是支付宝平台触发的
            boolean flag = AlipaySignature.rsaCheckV1(params, Constants.ALIPAY_PUBLIC_KEY, "UTF-8", Constants.SIGN_TYPE);
            if (flag){
                String outTradeNo  = new String(params.get("out_trade_no").getBytes("ISO-8859-1"),"UTF-8");
                String tradeNo = new String(params.get("trade_no").getBytes("ISO-8859-1"),"UTF-8");
                String totalAmount = new String(params.get("total_amount").getBytes("ISO-8859-1"),"UTF-8");
                Order order = Order.builder()
                        .orderId(tradeNo)
                        // 商户订单号
                        .productId(outTradeNo)
                        .price(totalAmount).build();
                String result = alipayStrategy.pay(order);
                return result;
            }
        }catch (Exception e){
            throw new RuntimeException(e);
        }

        return "支付失败!!请过段时间重试";

    }

    public String getPayUrl(String productId, Float price, Integer payType) {
        Order order = (Order) redisUtils.get(productId);
        order.setPrice(String.valueOf(price));
        return payFacade.pay(order,payType);
    }
}
